﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;
using Microsoft.Phone.Tasks;
using System.Text;
using System.Diagnostics;
using GreekWP7.HelperClasses;

namespace GreekWP7
{
    public partial class MainPage : PhoneApplicationPage
    {

        /*--------------------------------------------------------------------------------------------------*\
         * Series of events when touching on a WP7 button is
         * 1.MouseEnter
         * 2.MouseMove
         * 3.MouseLeave
        \*--------------------------------------------------------------------------------------------------*/


        EmailAddressChooserTask emailAddressChooserTask = new EmailAddressChooserTask();
        PhoneNumberChooserTask phoneNumberChooserTask = new PhoneNumberChooserTask();

        List<string> KeyboardLanguages;
        int currentLanguageIndex = 1;

        public int TextIndex { get; set; }

        KeyboardState keyboardState = KeyboardState.AlphabetUpperCase;

        public readonly string IsLetter = "IsLetter";
        public readonly string NumericButtonText = "&123";
        public readonly string AlphabetButtonText = "ABC";

        private readonly SolidColorBrush TextBrush;
        private readonly SolidColorBrush AccentBrush;

        private string ClickedButtonID;

        public MainPage()
        {
            InitializeComponent();
            TextBrush = new SolidColorBrush((Color)this.Resources["PhoneForegroundColor"]);
            AccentBrush = new SolidColorBrush((Color)this.Resources["PhoneAccentColor"]);
            this.Loaded += MainPage_Loaded;
        }

        void MainPage_Loaded(object sender, RoutedEventArgs e)
        {
            KeyboardLanguages = new List<string>(KeyboardInfoUtilities.Languages.Keys);
            SetLanguage();

            RecoverFromTombStoning();

            phoneNumberChooserTask.Completed += new EventHandler<PhoneNumberResult>(PhoneNumberChooserTask_Completed);
            emailAddressChooserTask.Completed += new EventHandler<EmailResult>(EmailAddressChooserTask_Completed);

        }

        private void RecoverFromTombStoning()
        {
            string x = (App.Current as App).TextBlockText;
            if (!string.IsNullOrEmpty(x))
            {

                foreach (char c in x)
                {
                    textBlock.Inlines.Add(new Run() { Text = c.ToString() });
                }

                textBlock.Inlines[textBlock.Inlines.Count - 1].Foreground = AccentBrush;
                TextIndex = textBlock.Text.Length;
            }
        }


        public string TextBlockText
        {
            get
            {
                return textBlock.Text;
            }
            set
            {
                textBlock.Text = value;
            }
        }


        private void Button_MouseEnter(object sender, RoutedEventArgs e)
        {
        }

        private void Button_MouseMove(object sender, RoutedEventArgs e)
        {
            Button button = sender as Button;
            if (button.Tag != null && button.Tag.ToString() == IsLetter)
            {
                ShowRollover(button);
            }
        }

        private void ShowRollover(Button button)
        {
            rolloverBorder.Visibility = System.Windows.Visibility.Visible;
            rolloverBorder.Margin = new Thickness(button.Margin.Left - button.BorderThickness.Left, button.Margin.Top - button.Height, 0, 0);
        }

        private void button_MouseLeftButtonDown(object sender, RoutedEventArgs e)
        {

        }



        private void Button_Click(object sender, RoutedEventArgs e)
        {

            Button button = sender as Button;
            if (button == null)
                return;

            ClickedButtonID = button.Name;

            CheckRollover(button);

        }

        private void ProcessKey(Button button)
        {
            string buttonContent = button.Content as string;

            if (buttonContent == (string)space.Content) //space was hit
                buttonContent = " ";
            else if (button.Name == (string)caps.Name)//caps was hit
            {
                MakeCaps();
                return;
            }
            else if (buttonContent == "΄")
            {
                ShowAccent();
                return;
            }
            else if (buttonContent == (string)numeric.Content) //numeric was hit
            {
                if (keyboardState == KeyboardState.AlphabetUpperCase || keyboardState == KeyboardState.AlphabetLowerCaseNoAccent || keyboardState == KeyboardState.AlphabetLowerCaseAccent)
                {
                    keyboardState = KeyboardState.Numeric2;
                    ShowNumeric();
                    button.Content = AlphabetButtonText;
                }
                else if (keyboardState == KeyboardState.Numeric1 || keyboardState == KeyboardState.Numeric2)
                {
                    keyboardState = KeyboardState.AlphabetUpperCase;
                    SetLanguage();
                    button.Content = NumericButtonText;
                }

                return;
            }
            else if (button.Name == enter.Name)//enter was hit
            {
                buttonContent = Environment.NewLine;
            }
            else if (button.Name == delete.Name)//delete was hit
            {
                DeleteCharacter();
                return;
            }
            else if (button.Name == left.Name || button.Name == right.Name)//navigation button was clicked
            {
                MoveCursor(button);
                return;
            }
            else if (button.Name == language.Name)//change language
            {
                currentLanguageIndex += 1;
                SetLanguage();
                return;
            }


            textBlock.Inlines.Insert(TextIndex, (new Run() { Text = buttonContent, Foreground = AccentBrush }));

            if (TextIndex >= 1)
                textBlock.Inlines[TextIndex - 1].Foreground = TextBrush;

            TextIndex += 1;

            if (keyboardState == KeyboardState.AlphabetLowerCaseAccent)
            {
                keyboardState = KeyboardState.AlphabetLowerCaseNoAccent;
                SetLanguage();
            }
            else if (keyboardState == KeyboardState.AlphabetUpperCase)
            {
                keyboardState = KeyboardState.AlphabetLowerCaseNoAccent;
                SetLanguage();
            }
        }

        private void ShowAccent()
        {
            foreach (UIElement c in keysGrid.Children)
            {
                Button button = c as Button;
                if (button == null || button.Content.GetType() != typeof(string)) continue;

                if ((string)button.Tag == IsLetter && keyboardState == KeyboardState.AlphabetLowerCaseNoAccent)
                {
                    KeyInfo ki = KeyboardInfoUtilities.Languages[KeyboardLanguages[currentLanguageIndex]][button.Name];
                    button.Content = string.IsNullOrEmpty(ki.Accent) ? ki.Value : ki.Accent;
                }
                else if ((string)button.Tag == IsLetter && keyboardState == KeyboardState.AlphabetLowerCaseAccent)
                {
                    button.Content = KeyboardInfoUtilities.Languages[KeyboardLanguages[currentLanguageIndex]][button.Name].Value;
                }

                
            }
            if (keyboardState == KeyboardState.AlphabetLowerCaseAccent) keyboardState = KeyboardState.AlphabetLowerCaseNoAccent;
            else if (keyboardState == KeyboardState.AlphabetLowerCaseNoAccent) keyboardState = KeyboardState.AlphabetLowerCaseAccent;
        }

        private void CheckRollover(Button button)
        {
            if (button.Tag != null && button.Tag.ToString() == IsLetter)
            {
                rolloverTextBlock.Text = button.Content.ToString();
                rolloverBorder.Visibility = Visibility.Visible;
                rolloverBorder.Margin = new Thickness(button.Margin.Left - button.BorderThickness.Left, button.Margin.Top - button.Height, 0, 0);
            }
        }

        private void Button_MouseLeave(object sender, MouseEventArgs e)
        {
            if (sender is Button)
            {
                if (ClickedButtonID != (e.OriginalSource as Button).Name)
                    return;
                ProcessKey(sender as Button);
                this.rolloverBorder.Visibility = Visibility.Collapsed;
            }

        }

        private void keysGrid_MouseMove(object sender, MouseEventArgs e)
        {
            Button button = e.OriginalSource as Button;
            if (button is Button && (button as Button).Tag != null && (button as Button).Tag.ToString() == IsLetter)
            {
                ClickedButtonID = button.Name;
                ShowRollover(button);
            }
            else
            {
                rolloverBorder.Visibility = System.Windows.Visibility.Collapsed;
            }
        }

        private void DeleteCharacter()
        {
            if (TextIndex > 0)
            {
                textBlock.Inlines.RemoveAt(TextIndex - 1);
                if (TextIndex > 0) TextIndex--;
                if (TextIndex > 0) textBlock.Inlines[TextIndex - 1].Foreground = AccentBrush;
                else if (TextIndex == 0 && textBlock.Inlines.Count > 0)
                {
                    TextIndex++;
                    textBlock.Inlines[0].Foreground = AccentBrush;
                }
            }
        }

        private void SetLanguage()
        {
            if (currentLanguageIndex >= KeyboardLanguages.Count)
                currentLanguageIndex = 0;

            foreach (UIElement uie in keysGrid.Children)
            {
                if (!(uie is Button))
                    continue;

                Button button = uie as Button;

                if ((string)button.Tag != IsLetter)
                    continue;

                (uie as Button).Content = keyboardState == KeyboardState.AlphabetUpperCase ? KeyboardInfoUtilities.Languages[KeyboardLanguages[currentLanguageIndex]][button.Name].Caps
                    : KeyboardInfoUtilities.Languages[KeyboardLanguages[currentLanguageIndex]][button.Name].Value;
            }

            language.Content = KeyboardLanguages[currentLanguageIndex != KeyboardLanguages.Count - 1 ?
                currentLanguageIndex + 1 : 0];
        }

        private void MoveCursor(Button button)
        {
            if (button.Name == left.Name && TextIndex > 1)
            {
                textBlock.Inlines[TextIndex - 1].Foreground = TextBrush;
                textBlock.Inlines[TextIndex - 2].Foreground = AccentBrush;
                TextIndex--;
            }
            else if (button.Name == right.Name && TextIndex < textBlock.Text.Length)
            {
                textBlock.Inlines[TextIndex - 1].Foreground = TextBrush;
                textBlock.Inlines[TextIndex].Foreground = AccentBrush;
                TextIndex++;
            }

        }

        private void MakeCaps()
        {
            if (keyboardState == KeyboardState.AlphabetUpperCase)
            {
                foreach (UIElement c in keysGrid.Children)
                {
                    Button button = c as Button;
                    if (button == null || button.Content.GetType() != typeof(string)) continue;

                    if ((string)button.Tag == IsLetter)
                        button.Content = KeyboardInfoUtilities.Languages[KeyboardLanguages[currentLanguageIndex]][button.Name].Value;
                }
                keyboardState = KeyboardState.AlphabetLowerCaseNoAccent;
            }
            else if (keyboardState == KeyboardState.AlphabetLowerCaseNoAccent || keyboardState == KeyboardState.AlphabetLowerCaseAccent)
            {
                foreach (UIElement c in keysGrid.Children)
                {
                    Button button = c as Button;
                    if (button == null || button.Content.GetType() != typeof(string)) continue;

                    if ((string)button.Tag == IsLetter)
                        button.Content = KeyboardInfoUtilities.Languages[KeyboardLanguages[currentLanguageIndex]][button.Name].Caps;
                }
                keyboardState = KeyboardState.AlphabetUpperCase;

            }
            else if (keyboardState == KeyboardState.Numeric1 || keyboardState == KeyboardState.Numeric2)
            {
                ShowNumeric();
            }

        }

        #region Application Bar Buttons Event Handlers

        private void ApplicationBarIconButtonSMS_Click(object sender, EventArgs e)
        {
            phoneNumberChooserTask.Show();
        }

        void PhoneNumberChooserTask_Completed(object sender, PhoneNumberResult e)
        {
            if (e.Error == null)
            {
                if (e.TaskResult == TaskResult.OK)
                    Helpers.ShowSMSDialog(textBlock.Text, e.PhoneNumber);
                else
                    Helpers.ShowSMSDialog(textBlock.Text, string.Empty);
            }
        }



        private void ApplicationBarIconButtonEmail_Click(object sender, EventArgs e)
        {
            emailAddressChooserTask.Show();
        }

        void EmailAddressChooserTask_Completed(object sender, EmailResult e)
        {
            if (e.Error == null)
            {
                if (e.TaskResult == TaskResult.OK)
                    Helpers.ShowEmailDialog(textBlock.Text, e.Email);
                else
                    Helpers.ShowEmailDialog(textBlock.Text, string.Empty);

            }
        }


        private void ApplicationBarIconButtonGoogle_Click(object sender, EventArgs e)
        {
            WebBrowserTask task = new WebBrowserTask();
            task.URL = @"http://www.google.gr?q=" + Uri.EscapeDataString(HttpUtility.UrlEncode(textBlock.Text));
            task.Show();
        }

        private void ApplicationBarIconButtonBing_Click(object sender, EventArgs e)
        {
            WebBrowserTask task = new WebBrowserTask();
            task.URL = string.Format(@"http://m.bing.com/search/search.aspx?q={0}&go=&d=&dl=&pq=&a=results&MID=1", Uri.EscapeDataString(HttpUtility.UrlEncode(textBlock.Text)));
            task.Show();
        }


        #endregion


        private void ShowNumeric()
        {
            if (keyboardState == KeyboardState.Numeric1)
            {
                foreach (UIElement c in keysGrid.Children)
                {
                    Button button = c as Button;
                    if (button == null || button.Content.GetType() != typeof(string)) continue;
                    else if ((string)button.Tag == IsLetter)
                        button.Content = KeyboardInfoUtilities.SpecialCharacters[button.Name].Value;
                }

                keyboardState = KeyboardState.Numeric2;
            }
            else if (keyboardState == KeyboardState.Numeric2)
            {
                foreach (UIElement c in keysGrid.Children)
                {
                    Button button = c as Button;
                    if (button == null || button.Content.GetType() != typeof(string)) continue;
                    else if ((string)button.Tag == IsLetter)
                        button.Content = KeyboardInfoUtilities.SpecialCharacters[button.Name].Caps;
                }

                keyboardState = KeyboardState.Numeric1;
            }
        }

        private void aboutMnu_Click(object sender, EventArgs e)
        {
            NavigationService.Navigate(new Uri("/About.xaml", UriKind.Relative));
        }

        private void copyButton_Click(object sender, RoutedEventArgs e)
        {
            if (copyTextBox.Visibility == System.Windows.Visibility.Collapsed)
            {
                textBlock.Visibility = System.Windows.Visibility.Collapsed;
                copyTextBox.Visibility = System.Windows.Visibility.Visible;
                copyButton.Content = "Ακύρωση";
                copyTextBox.Text = textBlock.Text;

                foreach (UIElement c in keysGrid.Children)
                {
                    if (c is Button)
                        (c as Button).IsEnabled = false;
                }
            }
            else if (copyTextBox.Visibility == System.Windows.Visibility.Visible)
            {
                textBlock.Visibility = System.Windows.Visibility.Visible;
                copyTextBox.Visibility = System.Windows.Visibility.Collapsed;
                copyButton.Content = "Copy";

                foreach (UIElement c in keysGrid.Children)
                {
                    if (c is Button)
                        (c as Button).IsEnabled = true;
                }
            }
            
        }

    }


}
